<?php
/*
DEVELOPER NOTES:

*******************************************************************************************************
This package is a PHP implementation of Jacob Munson's cffpVerify.cfm (part of CFFormProtect) written
by Dave Shuck dshuck@gmail.com.  All calculations/algorithms are a direct port of Jacob's original code,
with exceptions noted in the NOTES section below.
*******************************************************************************************************

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CREATED     : 5 Oct 2012

USAGE       : Perform various tests on a form submission to ensure that a human submitted it.

DEPENDANCY  : NONE

NOTES       : Dave Shuck - created
			  Dave Shuck - 23 Mar 2007 - Added testTooManyUrls() method and call to the method in testSubmission()
			  Dave Shuck - 23 Mar 2007 - Removed the '0' padding in FormTime in testTimedSubmission() which was causing
			  								consistent failure on that test
			  Dave Shuck - 24 Mar 2007 - Added logFailure() method and the call to the method in testSubmission().  This
			  								code is still backwards compatable with older ini files that do not make use of
			  								the properties 'logFailedTests' and 'logFile'
			  Dave Shuck - 26 Mar 2007 - Altered the FormTime in testTimedSubmission() to use NumberFormat as the previous
			  								change caused exceptions before 10:00am.  (see comments in method)
			  Mary Jo Sminkey - 18 July 2007 - Added new function 'testSpamStrings' which allows the user to configure a list
			  									of text strings to test the form against. Similar to using Akismet but with no
			  									cost involved for commercial use and can be configured as needed for the spam
			  									received. Update Akismet function to log to same file and not log as passed if
			  									the key validation failed.
        	  Ben Elliott - 16 Jan 2009 - Added ability to specify ini config filename during init() and setConfig() with new cfargument 'ConfigFilename'. This new argument defaults to 'cffp.ini.cfm' for backwards compatability.
			  Mike Lerley - 05 Oct 2012 - Initial port to PHP.  Project hosted at http://code.google.com/p/phpformprotect/
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/

include('config.php');

function testSubmission() {
	global $phpfpConfig;
	$Pass=true;
	$TotalPoints=0;
	$TestResults=array();

	// Begin tests
	if($phpfpConfig['mouseMovement']) {
		// Test for mouse movement
		$TestResults['mouseMovement']=testMouseMovement();
		if(!$TestResults['mousemovement']['Pass']) {
			$TotalPoints+=$phpfpConfig['mouseMovementPoints'];
		}
	}

	if($phpfpConfig['usedKeyboard']) {
		// Test for used keyboard
		$TestResults['mouseMovement']=testUsedKeyboard($formData);
		if(!$TestResults['usedKeyboard']['Pass']) {
			$TotalPoints+=$phpfpConfig['usedKeyboardPoints'];
		}
	}

	if($phpfpConfig['timedFormSubmission']) {
		// Test for time taken on the form
		$TestResults['timedFormSubmission']=testTimedFormSubmission($formData);
		if(!$TestResults['timedFormSubmission']['Pass']) {
			$TotalPoints+=$phpfpConfig['timedFormPoints'];
		}
	}

	if($phpfpConfig['hiddenFormField']) {
		// Test for empty hidden form field
		$TestResults['hiddenFormField']=testHiddenFormField($formData);
		if(!$TestResults['hiddenFormField']['Pass']) {
			$TotalPoints+=$phpfpConfig['hiddenFieldPoints'];
		}
	}

	if($phpfpConfig['akismet']) {
		// Test Akismet
		$TestResults['akismet']=testAkismet($formData);
		if(!$TestResults['akismet']['Pass']) {
			$TotalPoints+=$phpfpConfig['akismetPoints'];
		}
	}

	if($phpfpConfig['tooManyUrls']) {
		// Test tooManyUrls
		$TestResults['tooManyUrls']=testTooManyUrls($formData);
		if(!$TestResults['tooManyUrls']['Pass']) {
			$TotalPoints+=$phpfpConfig['tooManyUrlsPoints'];
		}
	}

	if($phpfpConfig['teststrings']) {
		// Test spamStrings
		$TestResults['SpamStrings']=testSpamStrings($formData);
		if(!$TestResults['SpamStrings']['Pass']) {
			$TotalPoints+=$phpfpConfig['spamStringPoints'];
		}
	}

	if($phpfpConfig['projectHoneyPot']) {
		// Test Project Honey Pot
		$TestResults['ProjHoneyPot']=testProjHoneyPot($formData);
		if(!$TestResults['ProjHoneyPot']['Pass']) {
			$TotalPoints+=$phpfpConfig['projectHoneyPotPoints'];
		}
	}

	if($TotalPoints >= $phpfpConfig['failureLimit']) {
		$Pass=false;
		if($phpfpConfig['emailFailedTests']) {
			emailReport($TestResults,$TotalPoints);
		}
		if($phpfpConfig['logFailedTests']) {
			logFailure($TestResults,$TotalPoints,$phpfpConfig['logFile']);
		}
	}

	return $Pass;

}

/*************************/

function testMouseMovement() {
	global $phpfpConfig;
	$Result=array();
	# I make sure this form field exists, and it has a numeric value in it (the distance the mouse traveled)

	$Result['Pass']=false;

	if($_REQUEST['formfield1234567891'] && is_numeric($_REQUEST['formfield1234567891'])) {
		$Result['Pass']=true;
	}
	return $Result;
}

function testUsedKeyboard() {
	global $phpfpConfig;
	$Result=array();

	# I make sure this form field exists, and it has a numeric value in it (the amount of keys pressed by the user)
	$Result['Pass']=false;

	if($_REQUEST['formfield1234567892'] && is_numeric($_REQUEST['formfield1234567892'])) {
		$Result['Pass']=true;
	}
	return $Result;
}

function testTimedFormSubmission() {
	global $phpfpConfig;
	$Result=array();

	# I check the time elapsed from the begining of the form load to the form submission
	$Result['Pass']=true;

	$FormDate='';
	$FormTime='';

	$TimeArray=explode(',',$_REQUEST['formfield1234567893']);

	# Decrypt the initial form load time
	if($_REQUEST['formfield1234567893'] && count($TimeArray)==2) {
		$FormDate=$TimeArray[0]-19740206;
		if(strlen($FormDate)==7) {
			$FormDate="0$FormDate";
		}
		$FormTime=$TimeArray[1]-19740206;
		if(strlen($FormTime)) {
			// in original form, FormTime was always padded with a "0" below.  In my testing, this caused the timed test to fail
			// consistantly after 9:59am due to the fact it was shifting the time digits one place to the right with 2 digit hours.
			// To make this work I added NumberFormat()
			$FormTime=sprintf('%06d',$FormTime);
		}

		$FormDateTime=date_create_from_format('ymdHis',"$FormDate$FormTime");

		// Calculate how many seconds elapsed
		$now=new DateTime();
		$diff=date_diff($FormDateTime,$now);
		$hrs=$diff->h * 3600;
		$mins=$diff->i * 60;
		$secs=$diff->s;
		$Result['FormTimeElapsed']=$hrs+$mins+$secs;
		if($Result['FormTimeElapsed'] < $phpfpConfig['timedFormMinSeconds'] || $Result['FormTimeElapsed'] > $phpfpConfig['timedFormMaxSeconds']) {
			$Result['Pass']=false;
		}
	} else {
		$Result['Pass']=false;
	}
	return $Result;
}

function testHiddenFormField() {
	global $phpfpConfig;
	$Result=array();

	# I make sure the CSS hidden form field doesn't have a value
	$Result['Pass']=false;

	if(array_key_exists('formfield1234567894',$_REQUEST) && strlen($_REQUEST['formfield1234567894'])==0) {
		$Result['Pass']=true;
	}

	return $Result;
}

function testAkismet() {
	global $phpfpConfig;
	$Result=array();

	# I send form contents to the public Akismet service to validate that it's not 'spammy'"
	$Result['Pass']=true;

	$AkismetKeyIsValid=false;
	$AkismetHTTPRequest=true;
	$logFile=$phpfpConfig['logFile'];
	$ValidKey=false;

	# validate the Akismet API key
	$ch=curl_init("http://rest.akismet.com/1.1/verify-key");
	$fields=array(
			'key' => $phpfpConfig['akismetAPIKey'],
			'blog' => $phpfpConfig['akismetBlogURL'],
			'user_agent' => 'PHPFormProtect/1.0 | Akismet/2.5.3',
			);
	foreach($fields as $k=>$v) {
		$fields_string.=$k.'='.$v.'&';
	}
	rtrim($fields_string, '&');

	curl_setopt($ch,CURLOPT_TIMEOUT,10);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
	curl_setopt($ch,CURLOPT_POST,count($fields));
	curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

	$result=curl_exec($ch);

	curl_close($ch);

	if($AkismetHTTPRequest && $result=='valid') {
		$AkismetKeyIsValid=true;
		$Result['ValidKey']=true;
	}

	if($AkismetKeyIsValid) {
		$ch=curl_init('http://'.$phpfpConfig['akismetAPIKey'].".rest.akismet.com/1.1/comment-check");
		$fields=array(
				'key' => $phpfpConfig['akismetAPIKey'],
				'blog' => $phpfpConfig['akismetBlogURL'],
				'user_ip' => $_SERVER['REMOTE_ADDR'],
				'user_agent' => 'PHPFormProtect/1.0 | Akismet/2.5.3',
				'referrer' => $_SERVER['HTTP_REFERER'],
				'comment_author' => $_REQUEST[$phpfpConfig['akismetFormNameField']],
				'comment_content' => $_REQUEST[$phpfpConfig['akismetFormBodyField']],
		);
		if($phpfpConfig['akismetFormEmailField']) {
			$fields['comment_author_email']=$_REQUEST[$phpfpConfig['akismetFormEmailField']];
		}
		if($phpfpConfig['akismetFormURLField']) {
			$fields['comment_author_url']=$_REQUEST[$phpfpConfig['akismetFormURLField']];
		}

		foreach($fields as $k=>$v) {
			$fields_string.=$k.'='.$v.'&';
		}
		rtrim($fields_string, '&');

		curl_setopt($ch,CURLOPT_TIMEOUT,10);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
		curl_setopt($ch,CURLOPT_POST,count($fields));
		curl_setopt($ch,CURLOPT_POSTFIELDS,$fields_string);

		$result=curl_exec($ch);

		curl_close($ch);

		if($AkismetHTTPRequest && $result=='true') {
			$Result['Pass']=false;
		}
	} else {
		log_error("Akismet API Key is invalid");
	}

	return $Result;
}

function testTooManyUrls() {
	global $phpfpConfig;
	$Result=array();

	# I test whether too many URLs have been submitted in fields
	$Result['Pass']=true;
	$UrlCount=0;

	foreach($_REQUEST as $field) {
		$UrlCount+=preg_match_all('@((https?://)?([-\w]+\.[-\w\.]+)+\w(:\d+)?(/([-\w/_\.]*(\?\S+)?)?)*)@',$field,$m);
	}

	if($UrlCount >= $phpfpConfig['tooManyUrlsMaxUrls']) {
		$Result['Pass']=false;
	}

	return $Result;
}

function testSpamStrings() {
	global $phpfpConfig;
	$Result=array();

	# I test whether any of the configured spam strings are found in the form submission
	$Result['Pass']=true;

	$value=0;
	$teststrings=$phpfpConfig['spamstrings'];
	$teststrings=str_replace(',','|',$teststrings);
	$wordsPattern='#('.$teststrings.')#i';
	$checkfield = '';

	# Loop through the list of spam strings to see if they are found in the form submission
	foreach($_REQUEST as $field) {
		if($Result['Pass']) {
			$found=preg_match($wordsPattern, $field);
			if($found) {
				$Result['Pass']=false;
			}
		}
	}

	return $Result;
}

function testProjHoneyPot() {
	global $phpfpConfig;
	$Result=array();

	# I send the user's IP address to the Project Honey Pot service to check if it's from a known spammer.
	$Result['Pass']=true;

	$apiKey=$phpfpConfig['projectHoneyPotAPIKey'];
	$visitorIP=$_SERVER['REMOTE_ADDR'];
	$reversedIP='';
	$addressFound=1;
	$isSpammer=0;
	$inetObj='';
	$hostNameObj='';
	$projHoneypotResult='';
	$resultArray=array();
	$threatScore='';
	$classification='';

	$ip=explode('.',$visitorIP);
	$revip=array_reverse($ip);
	$reversedIP=implode('.',$ip);
	#$reversedIP='38.46.41.74';	// bad ip
	$projHoneypotResult=gethostbyname("$apiKey.$reversedIP.dnsbl.httpbl.org");

	if($projHoneypotResult=="$apiKey.$reversedIP.dnsbl.httpbl.org") {
		$addressFound=0;
	}

	if($addressFound) {
		$resultArray=explode('.',$projHoneypotResult);
		$threatScore=$resultArray[2];
		$classification=$resultArray[3];
		if($threatScore>10 && $classification>1) {
			$isSpammer++;
		}
	}

	if($isSpammer) {
		$Result['Pass']=false;
	}

	return $Result;
}

function emailReport($TestResults,$TotalPoints) {
	global $phpfpConfig;

	$falsePositiveURL='';
	$missedSpamURL='';

	# Here is where you might want to make some changes, to customize what happens
	# if a spam message is found.  depending on your system, you can either just use
	# my code here, or email yourself the failed test, or plug into your system
	# in the best way for your needs

	$message="This message was marked as spam because:<ol>";

	if($TestResults['mouseMovement'] && !$TestResults['mouseMovement']['Pass']) {
		$message.="<li>No mouse movement was detected.</li>";
	}

	if($TestResults['usedKeyboard'] && !$TestResults['usedKeyboard']['Pass']) {
		$message.="<li>No keyboard activity was detected.</li>";
	}

	if($TestResults['timedFormSubmission'] && !$TestResults['timedFormSubmission']['Pass']) {
		if($_REQUEST['formfield1234567893']) {
			$message.="<li>The time it took to fill out the form was ";
			if($_REQUEST['formfield1234567893'] < $phpfpConfig['timedFormMinSeconds']) {
				$message.="too short.";
			} elseif($_REQUEST['formfield1234567893'] > $phpfpConfig['timedFormMaxSeconds']) {
				$message.="too long.";
			}
			$message.="It took them ".$TestResults['timedFormSubmission']['FormTimeElapsed']." seconds to submit the form, and your allowed threshold is $phpfpConfig[timedFormMinSeconds]-$phpfpConfig[timedFormMaxSeconds] seconds.";
			$message.="</li>";
		} else {
			$message.="<li>The time it took to fill out the form did not fall within your configured threshold of $phpfpConfig[timedFormMinSeconds]-$phpfpConfig[timedFormMaxSeconds] seconds.  Also, I think the form data for this field was tampered with by the	spammer.</li>";
		}
	}

	if($TestResults['hiddenFormField'] && !$TestResults['hiddenFormField']['Pass']) {
		$message.="<li>The hidden form field that is supposed to be blank contained data.</li>";
	}

	if($TestResults['SpamStrings'] && !$TestResults['SpamStrings']['Pass']) {
		$message.="<li>One of the configured spam strings was found in the form submission.</li>";
	}

	if($TestResults['akismet'] && !$TestResults['akismet']['Pass']) {
		$message.="<li>Akismet thinks this comment is spammy.</li>";
	}

	# TODO: port akismet reporting code
	/*
					<cfif StructKeyExists(arguments.TestResults,"akismet") AND NOT arguments.TestResults.akismet.Pass>
						<!--- The next few lines build the URL to submit a false
									positive notification to Akismet if this is not spam --->
						<cfset falsePositiveURL = replace("#getConfig().akismetBlogURL#cfformprotect/akismetFailure.cfm?type=ham","://","^^","all")>
						<cfset falsePositiveURL = replace(falsePositiveURL,"//","/","all")>
						<cfset falsePositiveURL = replace(falsePositiveURL,"^^","://","all")>
						<cfset falsePositiveURL = falsePositiveURL&"&user_ip=#urlEncodedFormat(cgi.remote_addr,'utf-8')#">
						<cfset falsePositiveURL = falsePositiveURL&"&referrer=#urlEncodedFormat(cgi.http_referer,'utf-8')#">
						<cfset falsePositiveURL = falsePositiveURL&"&comment_author=#urlEncodedFormat(form[getConfig().akismetFormNameField],'utf-8')#">
						<cfif getConfig().akismetFormEmailField neq "">
						<cfset falsePositiveURL = falsePositiveURL&"&comment_author_email=#urlEncodedFormat(form[getConfig().akismetFormEmailField],'utf-8')#">
						</cfif>
						<cfif getConfig().akismetFormURLField neq "">
						<cfset falsePositiveURL = falsePositiveURL&"&comment_author_url=#urlEncodedFormat(form[getConfig().akismetFormURLField],'utf-8')#">
						</cfif>
						<cfset falsePositiveURL = falsePositiveURL&"&comment_content=#urlEncodedFormat(form[getConfig().akismetFormBodyField],'utf-8')#">
						<li>Akisment thinks this is spam, if it's not please mark this as a
						false positive by <cfoutput><a href="#falsePositiveURL#">clicking here</a></cfoutput>.</li>
					<cfelseif StructKeyExists(arguments.TestResults,"akismet") AND arguments.TestResults.akismet.ValidKey AND arguments.TestResults.akismet.Pass>
						<!--- The next few lines build the URL to submit a missed
									spam notification to Akismet --->
						<cfset missedSpamURL = replace("#getConfig().akismetBlogURL#cfformprotect/akismetFailure.cfm?type=spam","://","^^","all")>
						<cfset missedSpamURL = replace(missedSpamURL,"//","/","all")>
						<cfset missedSpamURL = replace(missedSpamURL,"^^","://","all")>
						<cfset missedSpamURL = missedSpamURL&"&user_ip=#urlEncodedFormat(cgi.remote_addr,'utf-8')#">
						<cfset missedSpamURL = missedSpamURL&"&referrer=#urlEncodedFormat(cgi.http_referer,'utf-8')#">
						<cfset missedSpamURL = missedSpamURL&"&comment_author=#urlEncodedFormat(form[getConfig().akismetFormNameField],'utf-8')#">
						<cfif getConfig().akismetFormEmailField neq "">
						<cfset missedSpamURL = missedSpamURL&"&comment_author_email=#urlEncodedFormat(form[getConfig().akismetFormEmailField],'utf-8')#">
						</cfif>
						<cfif getConfig().akismetFormURLField neq "">
						<cfset missedSpamURL = missedSpamURL&"&comment_author_url=#urlEncodedFormat(form[getConfig().akismetFormURLField],'utf-8')#">
						</cfif>
						<cfset missedSpamURL = missedSpamURL&"&comment_content=#urlEncodedFormat(form[getConfig().akismetFormBodyField],'utf-8')#">
						Akismet did not think this message was spam.  If it was, please <a href="#missedSpamURL#">notify Akismet</a> that it
						missed one.
					</cfif>
	*/

	if($TestResults['tooManyUrls'] && !$TestResults['tooManyUrls']['Pass']) {
		$message.="<li>There were too many URLs in the form contents</li>";
	}

	if($TestResults['ProjHoneyPot'] && !$TestResults['ProjHoneyPot']['Pass']) {
		$message.="<li>The user's IP address has been flagged by Project Honey Pot.</li>";
	}

	$message.="</ol>
				Failure score: $TotalPoints<br />
				Your failure threshold: $phpfpConfig[failureLimit]<br /><br />
				IP address: $_SERVER[REMOTE_ADDR]<br />
				User agent: $_SERVER[HTTP_USER_AGENT]<br />
				Previous page: $_SERVER[HTTP_REFERER]<br />
				Form variables:<br/><pre>";
	$message.=print_r($_REQUEST,true);
	$message.="</pre>";

	$headers="From: $phpfpConfig[emailFromAddress]\r\n";
	$headers.="MIME-Version: 1.0\r\n";
	$headers.="Content-Type: text/html; charset=UTF-8\r\n";

	mail($phpfpConfig['emailToAddress'],$phpfpConfig['emailSubject'],$message,$headers);

	# TODO: add mail server/authentication code
	#server="#getConfig().emailServer#"
	#username="#getConfig().emailUserName#"
	#password="#getConfig().emailPassword#"

}

function logFailure($TestResults,$TotalPoints,$LogFile) {
	global $phpfpConfig;

	$falsePositiveURL='';
	$missedSpamURL='';

	$LogText='Message marked as spam!   ';

	if($TestResults['mouseMovement'] && !$TestResults['mouseMovement']['Pass']) {
		$LogText.=" --- No mouse movement was detected.";
	}

	if($TestResults['usedKeyboard'] && !$TestResults['usedKeyboard']['Pass']) {
		$LogText.=" --- No keyboard activity was detected.";
	}

	if($TestResults['timedFormSubmission'] && !$TestResults['timedFormSubmission']['Pass']) {
		if($_REQUEST['formfield1234567893']) {
			$LogText.=" --- The time it took to fill out the form did not fall within your configured threshold of $phpfpConfig[timedFormMinSeconds]-$phpfpConfig[timedFormMaxSeconds] seconds.";
		} else {
			$LogText.=" --- The time it took to fill out the form did not fall within your configured threshold of $phpfpConfig[timedFormMinSeconds]-$phpfpConfig[timedFormMaxSeconds] seconds.  Also, I think the form data for this field was tampered with by the	spammer.";
		}
	}

	if($TestResults['hiddenFormField'] && !$TestResults['hiddenFormField']['Pass']) {
		$LogText.=" --- The hidden form field that is supposed to be blank contained data.";
	}

	if($TestResults['SpamStrings'] && !$TestResults['SpamStrings']['Pass']) {
		$LogText.=" --- One of the configured spam strings was found in the form submission.";
	}

	# TODO: port akismet reporting code
	/*
		<cfif StructKeyExists(arguments.TestResults,"akismet") AND NOT arguments.TestResults.akismet.Pass>
			<!--- The next few lines build the URL to submit a false
						positive notification to Akismet if this is not spam --->
			<cfset falsePositiveURL = replace("#getConfig().akismetBlogURL#cfformprotect/akismetFailure.cfm?type=ham","://","^^","all")>
			<cfset falsePositiveURL = replace(falsePositiveURL,"//","/","all")>
			<cfset falsePositiveURL = replace(falsePositiveURL,"^^","://","all")>
			<cfset falsePositiveURL = falsePositiveURL&"&user_ip=#urlEncodedFormat(cgi.remote_addr,'utf-8')#">
			<cfset falsePositiveURL = falsePositiveURL&"&referrer=#urlEncodedFormat(cgi.http_referer,'utf-8')#">
			<cfset falsePositiveURL = falsePositiveURL&"&comment_author=#urlEncodedFormat(form[getConfig().akismetFormNameField],'utf-8')#">
			<cfif getConfig().akismetFormEmailField neq "">
				<cfset falsePositiveURL = falsePositiveURL&"&comment_author_email=#urlEncodedFormat(form[getConfig().akismetFormEmailField],'utf-8')#">
			</cfif>
			<cfif getConfig().akismetFormURLField neq "">
				<cfset falsePositiveURL = falsePositiveURL&"&comment_author_url=#urlEncodedFormat(form[getConfig().akismetFormURLField],'utf-8')#">
			</cfif>
			<cfset falsePositiveURL = falsePositiveURL&"&comment_content=#urlEncodedFormat(form[getConfig().akismetFormBodyField],'utf-8')#">
			<cfset LogText = LogText & "--- Akisment thinks this is spam, if it's not please mark this as a
							false positive by visiting: #falsePositiveURL#" />
		<cfelseif StructKeyExists(arguments.TestResults,"akismet") AND arguments.TestResults.akismet.ValidKey AND arguments.TestResults.akismet.Pass>
			<!--- The next few lines build the URL to submit a missed
						spam notification to Akismet --->
			<cfset missedSpamURL = replace("#getConfig().akismetBlogURL#cfformprotect/akismetFailure.cfm?type=spam","://","^^","all")>
			<cfset missedSpamURL = replace(missedSpamURL,"//","/","all")>
			<cfset missedSpamURL = replace(missedSpamURL,"^^","://","all")>
			<cfset missedSpamURL = missedSpamURL&"&user_ip=#urlEncodedFormat(cgi.remote_addr,'utf-8')#">
			<cfset missedSpamURL = missedSpamURL&"&referrer=#urlEncodedFormat(cgi.http_referer,'utf-8')#">
			<cfset missedSpamURL = missedSpamURL&"&comment_author=#urlEncodedFormat(form[getConfig().akismetFormNameField],'utf-8')#">
			<cfif getConfig().akismetFormEmailField neq "">
				<cfset missedSpamURL = missedSpamURL&"&comment_author_email=#urlEncodedFormat(form[getConfig().akismetFormEmailField],'utf-8')#">
			</cfif>
			<cfif getConfig().akismetFormURLField neq "">
				<cfset missedSpamURL = missedSpamURL&"&comment_author_url=#urlEncodedFormat(form[getConfig().akismetFormURLField],'utf-8')#">
			</cfif>
			<cfset missedSpamURL = missedSpamURL&"&comment_content=#urlEncodedFormat(form[getConfig().akismetFormBodyField],'utf-8')#">
			<cfset LogText = LogText & "--- Akismet did not think this message was spam.  If it was, please visit: #missedSpamURL#" />
		</cfif>
	*/

	if($TestResults['tooManyUrls'] && !$TestResults['tooManyUrls']['Pass']) {
		$LogText.=" --- There were too many URLs in the form contents.";
	}

	if($TestResults['ProjHoneyPot'] && !$TestResults['ProjHoneyPot']['Pass']) {
		$LogText.=" --- The user's IP address has been flagged by Project Honey Pot.";
	}

	$LogText.="--- Failure score: $TotalPoints.  Your failure threshold: $phpfpConfig[failureLimit].  IP address: $_SERVER[REMOTE_ADDR] 	User agent: $_SERVER[HTTP_USER_AGENT]	Previous page: $_SERVER[HTTP_REFERER]\n";

	error_log($LogText,3,$LogFile);
}

?>